package com.magina.nety.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import com.magina.nety.config.TestDemo;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;
import java.text.NumberFormat;
import java.util.*;

@Slf4j
public class ListUtils {

    public static void main(String[] args) {

        System.out.println(DateUtil.date(1558915200000L));
        System.out.println(DateUtil.date(1559520000000L));
        System.out.println(DateUtil.date(1560124800000L));
        System.out.println(DateUtil.date(1560729600000L));
//        DateUtil.
        System.out.println("2019".compareTo("小计"));
        List<TestDemo> list = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DAY_OF_YEAR,i);
            calendar.getTime();
            String dateTime  = DateUtil.format(calendar.getTime(),"yyyy-MM-dd");
            calendar.add(Calendar.DAY_OF_YEAR,1);
            String afterTime  = DateUtil.format(calendar.getTime(),"yyyy-MM-dd");
            TestDemo testDemo = TestDemo.builder().id(UUID.randomUUID().toString())
                    .date(dateTime + " - " +afterTime)
                    .name("test" + i)
                    .code(i+"code").build();
            list.add(testDemo);
        }
        list.add(TestDemo.builder().id(UUID.randomUUID().toString())
                .date("xiaoji" )
                .name("test" )
                .code("code").build());
        list.add(TestDemo.builder().id(UUID.randomUUID().toString())
                .date("*小计" )
                .name("test" )
                .code("code").build());
        sort(list,true,"date");
        System.out.println(list);
        sort(list,false,"date");
        System.out.println(list);
    }

        public static <E> void sort(List<E> list, final boolean isAsc, final String... sortnameArr) {
            Collections.sort(list, new Comparator<E>() {

                public int compare(E a, E b) {
                    int ret = 0;
                    try {
                        for (int i = 0; i < sortnameArr.length; i++) {
                            ret = ListUtils.compareObject(sortnameArr[i], isAsc, a, b);
                            if (0 != ret) {
                                break;
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return ret;
                }
            });
        }

        public static <E> void sort(List<E> list, final List<String> sortnameArr, final List<Boolean> typeArr) {
            if (sortnameArr.size() != typeArr.size()) {
                throw new RuntimeException("属性数组元素个数和升降序数组元素个数不相等");
            }
            Collections.sort(list, new Comparator<E>() {
                public int compare(E a, E b) {
                    int ret = 0;
                    try {
                        for (int i = 0; i < sortnameArr.size(); i++) {
                            ret = ListUtils.compareObject(sortnameArr.get(i), typeArr.get(i), a, b);
                            if (0 != ret) {
                                break;
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return ret;
                }
            });
        }


        private static <E> int compareObject(final String sortname, final boolean isAsc, E a, E b) throws Exception {
            int ret;
            Object value1 = ListUtils.forceGetFieldValue(a, sortname);
            Object value2 = ListUtils.forceGetFieldValue(b, sortname);
            String str1 = value1.toString();
            String str2 = value2.toString();
            if (value1 instanceof Number && value2 instanceof Number) {
                int maxlen = Math.max(str1.length(), str2.length());
                str1 = ListUtils.addZero2Str((Number) value1, maxlen);
                str2 = ListUtils.addZero2Str((Number) value2, maxlen);
            } else if (value1 instanceof Date && value2 instanceof Date) {
                long time1 = ((Date) value1).getTime();
                long time2 = ((Date) value2).getTime();
                int maxlen = Long.toString(Math.max(time1, time2)).length();
                str1 = ListUtils.addZero2Str(time1, maxlen);
                str2 = ListUtils.addZero2Str(time2, maxlen);
            }
            if (isAsc) {
                ret = str1.compareTo(str2);
            } else {
                ret = str2.compareTo(str1);
            }
            return ret;
        }

        public static String addZero2Str(Number numObj, int length) {
            NumberFormat nf = NumberFormat.getInstance();
            // 设置是否使用分组
            nf.setGroupingUsed(false);
            // 设置最大整数位数
            nf.setMaximumIntegerDigits(length);
            // 设置最小整数位数
            nf.setMinimumIntegerDigits(length);
            return nf.format(numObj);
        }

        public static Object forceGetFieldValue(Object obj, String fieldName) throws Exception {

//            Field field = obj.getClass().getField(fieldName);
//
//            Object object = null;
//            boolean accessible = field.isAccessible();
//            if (!accessible) {
//                // 如果是private,protected修饰的属性，需要修改为可以访问的
//                field.setAccessible(true);
//                object = field.get(obj);
//                // 还原private,protected属性的访问性质
//                field.setAccessible(accessible);
//                return object;
//            }
//            object = field.get(obj);
            if(null != fieldName && fieldName.length() > 0){
                fieldName  = CamelToUnderlineUtils.underlineToCamel(fieldName);
            }
            StringBuffer buffer=new StringBuffer();
            buffer.append("get").append(fieldName.substring(0,1).toUpperCase()).append(fieldName.substring(1));
            Method method = obj.getClass().getMethod(buffer.toString());
          //  log.info("Get method name {}","get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1));
            return method.invoke(obj);
        }

        public static <T> int getSize(Iterable<T> iterable){
            if (iterable instanceof Collection) {
                return ((Collection<?>) iterable).size();
            } else {
                int count = 0;
                Iterator iterator = iterable.iterator();
                while(iterator.hasNext()) {
                    iterator.next();
                    count++;
                }
                return count;
            }
        }
}
